package com.websocket.server;


import com.websocket.writer.PatchLogShowDTO;
import com.websocket.writer.TextFileWriter;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import static org.apache.logging.log4j.message.MapMessage.MapFormat.JSON;

@Component
@ServerEndpoint(value = "/webSocket/app/{appResourceId}/patchplan/{planId}/job/{jobId}/patchgroup/{groupId}/server/{ip}/log")
@Slf4j
@Getter
@Setter
public class PatchLogWebSocketUtils {

    private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();
    private static CopyOnWriteArraySet<PatchLogWebSocketUtils> webSocketSet = new CopyOnWriteArraySet<>();
    private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private String appResourceId;

    private Long planId;

    private Long jobId;

    private Long groupId;

    private String ip;

    private Session session;


    private String uId = null;

    private TextFileWriter textFileWriter = new TextFileWriter();


    @OnOpen
    public void onOpen(@PathParam("appResourceId") String appResourceId,
                       @PathParam("planId") Long planId,
                       @PathParam("jobId") Long jobId,
                       @PathParam("groupId") Long groupId,
                       @PathParam("ip") String ip,
                       Session session) {
        this.session = session;
        this.appResourceId = appResourceId;
        this.planId = planId;
        this.jobId = jobId;
        this.groupId = groupId;
        this.ip = ip;

        webSocketSet.add(this);

        this.uId = String.valueOf(planId) + groupId + ip;
        sessionPool.put(uId, session);
        log.info("`sessionId` :{}", uId);
        String msg = formatter.format(LocalDateTime.now())+"  new connection，id："+session.getId()+"\n";
        textFileWriter.buildDataList(msg);
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void onClose() {
        if (sessionPool.containsKey(uId)) {
            sessionPool.remove(uId);
            webSocketSet.remove(this);
        }
        String msg = formatter.format(LocalDateTime.now())+"  connection closed，id："+session.getId()+"\n";
        textFileWriter.buildDataList(msg);
        log.info("onClose webSockets total：{}", webSocketSet.size());
    }

    @OnMessage
    public void onMessage(String start) {
        String msg = formatter.format(LocalDateTime.now())+"  server received message："+start+"\n";
        textFileWriter.buildDataList(msg);
        try {
            if (sessionPool.containsKey(uId)) {
                getLogInfo(start);
            }
        } catch (Exception e) {
            log.error("error, msg:{}", e);
        }
    }

    public void getLogInfo(String start) {
        try {
            PatchLogShowDTO patchLogShowDTO = PatchLogShowDTO.builder()
                    .patchUnionId(jobId+"_"+ip)
                    .patchJobId(jobId+"")
                    .ip(ip)
                    .start(start).build();

            this.session.getBasicRemote().sendText(patchLogShowDTO.toString());
        } catch (Exception e) {
            log.error("error:{}", e);
        }
    }


    public static void sendMessage(String uid, String message) {
        try {
            if (sessionPool.containsKey(uid)) {
                sessionPool.get(uid).getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            log.error("error, msg:{}", e);
        }
    }

    public static void print() {
        try {
            Set<Map.Entry<String, Session>> entries = sessionPool.entrySet();

            for (Map.Entry<String, Session> entry : entries) {
                String key = entry.getKey();
                Session value = entry.getValue();
                // 处理key和value
                System.out.println("Key: " + key + ", Value: " + value);
            }

        } catch (Exception e) {
            log.error("error, msg:{}", e);
        }
    }
}
